package chapter6;

import java.util.Scanner;

/****************************************************************
 * Author：icynlau
 * Description: 这道打印日历——使用3.21中的泽勒一致性改进课本程序清单6.12
 * 虽然很懒得写，但是还是写了(抄了20：00-)
 * Date:2021/4/6
 * ***************************************************************
 */
public class exc6_34 {
	
	public static void main(String[] args) {
		
		Scanner input=new Scanner(System.in);
		
		System.out.print("Enter full year (e.g., 2012): ");
		int year=input.nextInt();
		
		System.out.print("Enter month as number between 1 and 12: ");
		int month=input.nextInt();
		
		printMonth(year,month);
		
	}
	
	public static void printMonth(int year,int month) {
		
		printMonthTitle(year,month);
		
		printMonthBody(year,month);
		
	}
	
	public static void printMonthTitle(int year,int month) {
		
		System.out.print("           "+getMonthName(month)+" "+year+"\n");
		System.out.print("------------------------------------\n");
		System.out.print("SUN   MON   TUE   WED   THU   FRI   SAT\n");
		
	}
	
	public static String getMonthName(int month) {
		
		String monthName="";
		month-=1;
		switch(month) {
		case 0:monthName="January";break;
		case 1:monthName="February";break;
		case 2:monthName="March";break;
		case 3:monthName="April ";break;
		case 4:monthName="May";break;
		case 5:monthName="June";break;
		case 6:monthName="July";break;
		case 7:monthName="August";break;
		case 8:monthName="September";break;
		case 9:monthName="October";break;
		case 10:monthName="November";break;
		case 11:monthName="December";break;
		}
		
		return monthName;
	}
	
	public static void printMonthBody(int year,int month) {
		
		int startDay=getStartDay(year,month);
		
		int numberOfDaysInMonth= getNumberOfDaysInMonth(year,month);
		
		int i=0;

		for(i=0;i<startDay;i++) {
			
			System.out.print("\t    ");
			
		}
		for(i=0;i<=numberOfDaysInMonth;i++) {
			
			System.out.printf("%-8d",i+1);
			if((i+startDay)%7==0&&i!=0)
				System.out.println();
			
		}
		
		System.out.println();
		
		
		
	}
	
	
	public static int getStartDay(int year,int month) {
		/*
		final int START_DAY_FOR_JAN_1_1800=3;
		
		int totalNumberOfDays=getTotalNumberOfDays(year,month);
		
		return (totalNumberOfDays+ START_DAY_FOR_JAN_1_1800)%7;
		//这一句比我自己的显示日期和时间的程序写得好，直接求历经时间的天数总和，直接取余，不用麻烦得一个月一个月得加
		*/
		
		//用泽勒法改进
		int q=1;
		int m=month;
		int k=year%100;
		int j=Math.abs(year/100);
		
		return (q+(26*(m+1)/10)+k+k/4+j/4+5*j)%7;
		
	}
	
	public static int getTotalNumberOfDays(int year,int month) {
		int total=0;
		
		for(int i=1800;i<year;i++) {
			
			if(isLeapYear(i)) {
				total=total+366;
			}else {
				total=total+365;
			}
		}
		for(int i=1;i<month;i++) {
			
			total=total+getNumberOfDaysInMonth(year,i);
			
		}
		
		return total;
		
	}
	
	public static int getNumberOfDaysInMonth(int year,int month) {
		
		if(month==1||month==3||month==5||month==7
				||month==8||month==10||month==12) {
			return 31;
		}
		
		if(month==4 ||month==6 ||month==9 ||month==11) {
			return 30;
		}
		
		if(month==2) return isLeapYear(year)? 29:28;
		
		return 0;
		
	}

	
	public static boolean isLeapYear(int year) {
		
		return year%400==0 ||(year%4==0 &&year %100!=0);
		
	}
}
